# MQTT Data Format

There are a few ways to send data to our MQTT API if you're writing your own client library.

The simplest way to send values to an IO Feed topic is to just send the value.  For example, a temperature sensor is going to produce numeric values like `22.587`.  If you're sending to `mosfet/feeds/photocell-one` you can use the raw number or a string. That means either `22.587` or `22.587` will be accepted as a numeric value. Adafruit IO does its best to treat data as numeric values so that we can show you your data as a chart on an Adafruit IO dashboard and through our [Charting API](https://io.adafruit.com/api/docs/#!/Data/chartData).


## Sending data with location

To tag your data with a location value, you'll either need to wrap it in a JSON object first or send it to the special `/csv` formatted MQTT topic.


## Sending JSON

JSON can be sent to either the base topic or the /json topic - for example `mosfet/feeds/photocell-one` or `mosfet/feeds/photocell-one/json`.
The proper format for location tagged JSON data is:

Example JSON topic object:

<% partial 'helpers/inline_code' do %>
```javascript
{
  "value": 22.587,
  "lat": 38.1123,
  "lon": -91.2325,
  "ele": 112
}
```
<% end %>

Specifically, JSON objects must include a `value` key, and may include `lat`, `lon`, and `ele` keys.

## Sending CSV

Alternatively, you can send location tagged data to `/csv` topics. In this example, that would be the topic `mosfet/feeds/photocell-one/csv` instead of `mosfet/feeds/photocell-one`. Both store data in the same feed. The format IO expects for location tagged CSV data is VALUE, LATITUDE, LONGITUDE, ELEVATION.

With the example data shown before, that means you could publish the string `"22.587,38.1123,-91.2325,112"` to `mosfet/feeds/photocell-one/csv`. to store the value `"22.587"` in the location `latitude: 38.1123`, `longitude: -91.2325`, `elevation: 112`.

An example is displayed below, which uses a simple Ruby MQTT library and the data shown, all these examples publish the same data to the same feed.

<% partial 'helpers/inline_code' do %>
```ruby
# first you'll need https://github.com/njh/ruby-mqtt
require 'mqtt'

username = 'test_username'
key      = 'not-a-real-key'
url      = "mqtts://#{ username }:#{ key }@io.adafruit.com"

mqtt_client = MQTT::Client.connect(url, 8883)

# simplest thing that could possibly work
mqtt_client.publish('test_username/feeds/example', 22.587)

# sending numbers as strings is fine, IO stores all data internally
# as strings anyways
mqtt_client.publish('test_username/feeds/example', '22.587')

# CSV formatted, no location
mqtt_client.publish('test_username/feeds/example/csv', '22.587')

# CSV formatted, with location
mqtt_client.publish('test_username/feeds/example/csv',
                  '22.587,38.1123,-91.2325,112')

# JSON formatted, no location
mqtt_client.publish('test_username/feeds/example', '{"value":22.587}')
mqtt_client.publish('test_username/feeds/example/json', '{"value":22.587}')

# JSON formatted, with location
mqtt_client.publish('test_username/feeds/example',
'{"value":22.587,"lat":38.1123,"lon":-91.2325,"ele":112}')
mqtt_client.publish('test_username/feeds/example/json',
'{"value":22.587,"lat":38.1123,"lon":-91.2325,"ele":112}')
```
<% end %>


## Sending JSON Data through Adafruit IO

Because Adafruit IO supports additional features beyond a basic MQTT brokering service, such as location tagging for data points,
the service supports data in the JSON format described above. Namely, the example JSON response on the sidebar.

JSON Response Format Example

<% partial 'helpers/inline_code' do %>
```javascript
  {
    "value": 22.587,
    "lat": 38.1123,
    "lon": -91.2325,
    "ele": 112
  }
```
<% end %>

This lets us store the individual value, `22.587`, and data about the value: its latitude, longitude, and elevation. Metadata!

But what happens when the value you want to send is itself JSON? Good news! There are a few solutions available to you in that situation.

### IO-Formatted JSON

The simplest way to send JSON data to Adafruit IO is to wrap it in the format described above. For example, if instead of `22.587`, I wanted to send something like, `{"sensor-1":22.587,"sensor-2":13.182}`, the "wrapped" version would look like this:

Example of IO-Formatted JSON

<% partial 'helpers/inline_code' do %>
```javascript
{
  "value": {"sensor-1":22.587,"sensor-2":13.182},
  "lat": 38.1123,
  "lon": -91.2325,
  "ele": 112
}
```
<% end %>

It's worth noting that because Adafruit IO parses the entire JSON object that you send it, any valid JSON will be parsed and when it is stored in our system and forwarded to any subscribers, it will be regenerated. The significance of that is that if you publish JSON data with whitespace, it will be stored and republished without whitespace, because our generator produces the most compact JSON format possible.

### Double-Encoded JSON Strings

The second way you can send JSON data as a value is to "double encode" it before sending, in which case IO will treat it as a raw string.
If you're using something like javascript's `JSON.stringify` function or Ruby's `JSON.generate`, double encoding means passing the result of
`JSON.stringify` through `JSON.stringify` a second time. In this node.js console example, you can see the difference:


Here's an example of sending double-encoded strings through Adafruit IO:

<% partial 'helpers/inline_code' do %>
```javascript
> JSON.stringify({"sensor-1":22.587,"sensor-2":13.182})
'{"sensor-1":22.587,"sensor-2":13.182}'
> JSON.stringify(JSON.stringify({"sensor-1":22.587,"sensor-2":13.182}))
'"{\"sensor-1\":22.587,\"sensor-2\":13.182}"'
```
<% end %>

The double encoded JSON string can be sent directly through Adafruit IO without interference from our processing system, because the processing system will not interpret it as JSON. In your receiving code, because the value passed through includes surrounding double quotes, you have to call your parse function twice to restore the JSON object.

Here's an example of interpreting double-encoded JSON Strings sent through Adafruit IO:

<% partial 'helpers/inline_code' do %>
```javascript
> var input = '"{\\\"sensor-1\\\":22.587,\\\"sensor-2\\\":13.182}"'
> JSON.parse(JSON.parse(input))
{ 'sensor-1': 22.587, 'sensor-2': 13.182 }
```
<% end %>

### Non-IO Formatted JSON

The third way you can send raw JSON data is to just send it. If Adafruit IO doesn't find a "value" key in the JSON object you send,
it will treat the whole blob as plain text and store and forward the data. That means with our example JSON object,
sending the string `{"sensor-1":22.587,"sensor-2":13.182}` will result in `{"sensor-1":22.587,"sensor-2":13.182}` being stored in IO and sent
to MQTT subscribers.


